// namespace definition
syslib.namespace("syslib.ui");

/**
 * The main UI class
 * @class syslib.ui
 * @version 0.5.3
 * @author Gabriel Ricci - gabrielricci@gmail.com
 * @static
 */
syslib.ui = {
	/** 
	 * The version
	 */ 
	version : "0.5.5",
	
	/**
	 * The status, to avoid more than one UI initialization
	 */
	started : false, 
	
	init: function(){
		if(this.started){
			return true;
		}
	
		// try to register the tags
		this.registerTags();

		// get the options
		var options = syslib.options;

		// load the effects
		if(__valid(options.enableFX)){
			// search the effects
			for(var i = 0; i < options.effects.length; i++){
				// get the effect
				var effect = options.effects[i];
				
				// load
				syslib.ui.fx.load(effect);
			}
		}
		
		// set as started
		this.started = true;
		
		// parse the body
		syslib.taglib.parseBody();
	},
	
	/**
	 * Register the components on the core of the lib
	 */
	registerTags : function(){
		/* panels */
		syslib.taglib.registerTag('xsplitterpanel', {
			namespaceName : "syslib.ui.XSplitterPanel",
			parser : "syslib.ui.XSplitterPanel"
		});
		syslib.taglib.registerTag('xsplitteritem', {
			namespaceName : "syslib.ui.XSplitterItem",
			parser : "syslib.ui.XSplitterItem"
		});
		syslib.taglib.registerTag('box', {
			namespaceName : "syslib.ui.Box",
			parser : "syslib.ui.BoxTag"
		});
		syslib.taglib.registerTag('dialog', {
			namespaceName : "syslib.ui.Dialog",
			parser : "syslib.ui.DialogTag"
		});
		syslib.taglib.registerTag('tabpanel', {
			namespaceName : "syslib.ui.TabPanel",
			parser : "syslib.ui.TabPanel"
		});
		syslib.taglib.registerTag('tabitem', {
			namespaceName : "syslib.ui.TabItem",
			parser : "syslib.ui.TabItemTag"
		});
		syslib.taglib.registerTag('accordeonmenu', {
			namespaceName : "syslib.ui.Accordeon",
			parser : "syslib.ui.AccordeonTag"
		});
		syslib.taglib.registerTag('accordeonitem', {
			namespaceName : "syslib.ui.AccordeonItem",
			parser : "syslib.ui.AccordeonItemTag"
		});
		syslib.taglib.registerTag('wizardpanel', {
			namespaceName : "syslib.ui.WizardPanel",
			parser : "syslib.ui.WizardPanel"
		});
		syslib.taglib.registerTag('wizardpanelheader', {
			namespaceName : "syslib.ui.WizardPanelHeader",
			parser : "syslib.ui.WizardPanelHeader"
		});
		syslib.taglib.registerTag('wizardstep', {
			namespaceName : "syslib.ui.WizardStep",
			parser : "syslib.ui.WizardStep"
		});
		syslib.taglib.registerTag('wizardstepheader', {
			namespaceName : "syslib.ui.WizardStepHeader",
			parser : "syslib.ui.WizardStepHeader"
		});
		syslib.taglib.registerTag('panel', {
			namespaceName : "syslib.ui.Panel",
			parser : "syslib.ui.PanelTag"
		});
		syslib.taglib.registerTag('simplepanel', {
			namespaceName : "syslib.ui.SimplePanel",
			parser : "syslib.ui.SimplePanelTag"
		});
		
		/* tree */
		syslib.taglib.registerTag("treenode", {
			namespaceName : "syslib.ui.tree.TreeNode", 
			parser : "syslib.ui.tree.TreeNodeTag"
		});
		
		/* separators */
		syslib.taglib.registerTag('horizontalseparator', {
			namespaceName : "syslib.ui.HorizontalSeparator",
			parser : "syslib.ui.HorizontalSeparator", 
			innerContent : false
		});
		syslib.taglib.registerTag('verticalseparator', {
			namespaceName : "syslib.ui.VerticalSeparator",
			parser : "syslib.ui.VerticalSeparator", 
			innerContent : false
		});
		
		/* toolbars */
		syslib.taglib.registerTag('toolbar', {
			namespaceName : "syslib.ui.Toolbar",
			parser : "syslib.ui.ToolbarTag"
		});
		
		/* form items */
		syslib.taglib.registerTag('tooltip', {
			namespaceName : "syslib.ui.Tooltip",
			parser : "syslib.ui.TooltipTag"
		});
		syslib.taglib.registerTag('buttonmenu', {
			namespaceName : "syslib.ui.ButtonMenu",
			parser : "syslib.ui.ButtonMenuTag"
		});
		syslib.taglib.registerTag('buttonitem', {
			namespaceName : "syslib.ui.ButtonItem",
			parser : "syslib.ui.ButtonItemTag"
		});
		syslib.taglib.registerTag('spinner', {
			namespaceName : "syslib.ui.Spinner",
			parser :  "syslib.ui.Spinner",
			innerContent : false
		});
		syslib.taglib.registerTag('calendar', {
			namespaceName : "syslib.ui.Calendar",
			parser :  "syslib.ui.Calendar",
			innerContent : false
		});
		syslib.taglib.registerTag('maskinput', {
			namespaceName : "syslib.ui.MaskInput",
			parser : "syslib.ui.MaskInput",
			innerContent : false
		});
		syslib.taglib.registerTag('texteditor', {
			namespaceName : "syslib.ui.TextEditor",
			parser : "syslib.ui.TextEditor"
		});
		syslib.taglib.registerTag('simplebutton', {
			namespaceName : "syslib.ui.Button",
			parser : "syslib.ui.ButtonTag"
		});
		syslib.taglib.registerTag('button', {
			namespaceName : "syslib.ui.Button",
			parser : "syslib.ui.ButtonTag"
		});
		syslib.taglib.registerTag('progressbar', {
			namespaceName : "syslib.ui.ProgressBar",
			parser :  "syslib.ui.ProgressBar",
			innerContent : false
		});
		
		/* layots */
		syslib.taglib.registerTag('columnlayout', {
			namespaceName : "syslib.ui.layout.ColumnLayout",
			parser :  "syslib.ui.layout.ColumnLayoutTag"
		});
		syslib.taglib.registerTag('columnlayout-column', {
			namespaceName : "syslib.ui.layout.ColumnLayout",
			parser :  "syslib.ui.layout.ColumnLayout_ColumnTag"
		});
		
		syslib.taglib.registerTag('borderlayout', {
			namespaceName : "syslib.ui.layout.BorderLayout",
			parser :  "syslib.ui.layout.BorderLayoutTag"
		});
		syslib.taglib.registerTag('borderlayout-item', {
			namespaceName : "syslib.ui.layout.BorderLayout",
			parser :  "syslib.ui.layout.BorderLayout_ItemTag"
		});
	}
};

/**
 * The element positioning class
 * @class syslib.ui.position
 * @author Gabriel Ricci
 * @static
 */
syslib.ui.position = {
	center : function(element, options){
		// check if the element is valid
		element = __id(element);
		if(!__valid(element)){
			// log and return
			syslib.messages.error("syslib.ui.position.center(): Invalid element!");
			return false;
		}
	
		// format the options
		options = __extend({}, options);
	
		// set a timeout to run this same funcion again (correct possible errors)
		if(options.lateExecution !== false){
			setTimeout(function(){
				syslib.ui.position.center(element, __extend(options, {
					lateExecution : false
				}));
			}, 100);
		}
	
		try{
			// remove from the body, if's there
			element.parentNode.removeChild(element);
		} catch(e){}

		// append to the body
		document.body.appendChild(element);
		
		// get the element dimension
		var Dimensions = syslib.element.getDimensions(element);
		
		// get the viewport size
		var viewportSize = syslib.ui.size.getViewportSize(); 
		
		// calcule the position to the body
		var leftMiddle = document.body.scrollLeft + ( viewportSize.width / 2);
		var topMiddle = document.body.scrollTop + ( viewportSize.height / 2);

		// calcule the final position based on the element size
		var posx = leftMiddle - (Dimensions.width / 2);
		var posy = topMiddle - (Dimensions.height / 2);
		
		// check if the y position is negative
		if(posy < 0){
			posy = 0;
		}

		// update the style
		element.style.position = 'absolute';
		element.style.left = posx + "px";
		element.style.top = posy + "px";
	
		// set the event
		if(options.setEvent !== false){
			syslib.event.listen('resize', window, function(){
				syslib.ui.position.center(element, __extend(options, {
					setEvent : false
				}));
			});
			syslib.event.listen('scroll', document.body, function(){
				syslib.ui.position.center(element, __extend(options, {
					setEvent : false
				}));
			});
			syslib.event.listen('scroll', window, function(){
				syslib.ui.position.center(element, __extend(options, {
					setEvent : false
				}));
			});
		}
	},

	getOffsets : function(element){
		element = __id(element);
		var top = 0; var left = 0;
		while (element.offsetParent){
			left 	+= element.offsetLeft;
			top  	+= element.offsetTop;
			element	=  element.offsetParent;
		}

		left += element.offsetLeft;
		top  += element.offsetTop;

		return {x: left, y: top};
	}, 
	
	getViewportPosition : function(element){
		var top		= 0;
		var left	= 0;

		try{
			while(syslib.util.valid(element.offsetParent)){
				left += (element.offsetLeft - element.offsetParent.scrollLeft);
				top  += (element.offsetTop - element.offsetParent.scrollTop);
				element = element.offsetParent;
			}
			top  += (element.offsetLeft);
			left += (element.offsetTop);
		} catch(e){
			syslib.messages.error("syslib.getViewportPosition(): " + e.message);
		}

		return {x: left, y: top};
	}
};

/**
 * The element size controling class
 * @class syslib.ui.size
 * @author Gabriel Ricci
 * @static
 */
syslib.ui.size = {
	setFullHeight : function(element, options){
		// get the element
		var element = __id(element);
		
		// check if the element is valid
		if(!__valid(element)){ return false; }
		
		// get the element absolute position and the window size
		var absPosition = syslib.ui.position.getViewportPosition(element);
		var windowSize	= this.getViewportSize();
		
		// format the options
		options = __extend({
			setEvent : true, 
			overflow : "auto"
		}, options);
		
		// calcule the height
		var height = windowSize.height - absPosition.y;
		
		// check if padding is needed
		if(__valid(options.padding) && !isNaN(parseInt(options.padding))){
			height -= parseInt(options.padding);
		}

		// update the height
		syslib.element.updateStyle(element, {
			"height" : height + "px", 
			"overflowY" : options.overflow 
		});

		// set the event
		if(options.setEvent !== false || options.setEvent === undefined){
			syslib.event.listen('resize', window, function(){
				syslib.ui.size.setFullHeight(element, __extend(options, {
					setEvent : false 
				}));
			});
		}
	},
	
	getOffsets : function(element){
		// get the element
		element = __id(element);
		
		// get the offsets and return
		return {width: element.offsetWidth, height: element.offsetHeight};
	}, 
	
	getWindowSize : function(){
		// get the offsets of the body
		return this.getOffsets(document.body);
	},
	
	getPageSizeWithScroll : function(){
		if (window.innerHeight && window.scrollMaxY) {// Firefox
			height = window.innerHeight + window.scrollMaxY;
			width = window.innerWidth + window.scrollMaxX;
		} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
			height = document.body.scrollHeight;
			width = document.body.scrollWidth;
		} else { // works in Explorer 6 Strict, Mozilla (not FF) and Safari
			height = document.body.offsetHeight;
			width = document.body.offsetWidth;
	  	}

		return {width: width, height: height};
	},
	
	getViewportSize : function(){
		// declare the variables
		var width;
 		var height;
 
 		// actual browsers method
 		if (typeof window.innerWidth != 'undefined'){
      		width = window.innerWidth;
      		height = window.innerHeight;
 		} else if (__valid(document.documentElement) && __valid(document.documentElement.clientWidth)){
 			// ie6 method
       		width = document.documentElement.clientWidth;
       		height = document.documentElement.clientHeight;
		} else {
			// older browsers method
       		width = document.getElementsByTagName('body')[0].clientWidth;
       		height = document.getElementsByTagName('body')[0].clientHeight;
 		}
 		
 		// return
 		return {width: width, height: height};
	}
};

/**
 * The user-interface utilities class
 * @class syslib.ui.util
 * @author Gabriel Ricci
 * @static
 */
syslib.ui.util = {
	_bodyMaskVisible : false, 
	_bodyMaskResizeEventSetted : false, 
		
	toggleChecks : function(controller, container){
		container = __id(container);
		if(!__valid(container)){alert('invalid!'); return false;}

		var checks = container.getElementsByTagName("input");
		for(var i = 0; i < checks.length; i++){
			var check = checks[i];
			if(check.getAttribute("type") != "checkbox" || check == controller || check.disabled === true){ continue; }
			check.checked = controller.checked;
		}
	}, 
	
	showBodyMask : function(zIndex){
		// declare the needed variables
		var mask;
	
		// get the viewport size
		var viewportSize = syslib.ui.size.getViewportSize();
		
		// get the scrollbar size
		var scrollHeight = document.body.scrollTop;
		var scrollWidth = document.body.scrollLeft;
		
		// create the mask
		if(__valid(__id("syslib-body-mask"))){
			mask = __id("syslib-body-mask");
		} else {
			mask = document.createElement("div");
			mask.id = "syslib-body-mask";
			mask.innerHTML = "&nbsp;";
		}
		 
		// update the style of the mask
		syslib.element.updateStyle(mask, {
			"backgroundColor" : "#000", 
			"color" : "#fff", 
			"position" : "absolute", 
			"height" : viewportSize.height + "px", 
			"width" : viewportSize.width + "px", 
			"top" : scrollHeight + "px",
			"left" : scrollWidth + "px",
			"zIndex" : zIndex, 
			"display" : "block", 
			"filter": 'alpha(opacity=25)',
			"-moz-opacity": ".25",
			"opacity": ".25"
		});
		
		// append to the body
		document.body.appendChild(mask);
		
		// show
		syslib.element.show(mask);
		
		// set as visible
		this._bodyMaskVisible = true;
		
		// set the resize event
		if(!this._bodyMaskEventsSetted){
			__evtListen("resize", window, function(){
				// check if the body mask is visible
				if(this._bodyMaskVisible){
					// update the size
					syslib.ui.util.showBodyMask();
				}
			}.applyTo(this));
			
			__evtListen("scroll", window, function(){
				// check if the body mask is visible
				if(this._bodyMaskVisible){
					// update the size
					syslib.ui.util.showBodyMask();
				}
			}.applyTo(this));
			
			__evtListen("scroll", document.body, function(){
				// check if the body mask is visible
				if(this._bodyMaskVisible){
					// update the size
					syslib.ui.util.showBodyMask();
				}
			}.applyTo(this));
			
			// set the resize event as setted
			this._bodyMaskEventsSetted = true;
		}
	}, 
	
	hideBodyMask : function(){
		// if the mask is valid, hide it
		if(__valid(__id("syslib-body-mask"))){
			syslib.element.hide(__id("syslib-body-mask"));
		}
		
		// set the visible property as false
		this._bodyMaskVisible = false;
	}
};

/**
 * Drag class
 * Options:
 *   - onstartdrag : function(element, controller) - Function called when the drag starts;
 *   - onstopdrag : function(element, controller) - Function called when the drag ends;
 *   - ondragging : function(element, controller) - Function called when dragging;
 *   - xmove : boolean(true, false) - Enable or disable the X moving;
 *   - ymove : boolean(true, false) - Enable or disable the Y moving;
 *   - alpha : boolean(true, false) - Enable or disable alpha when dragging;
 *   - reset : boolean(true, false) - Aways reset the element to the start position
 * @class syslib.ui.Drag
 * @author Gabriel Ricci
 */
syslib.ui.Drag = __class();
syslib.ui.Drag.prototype = {
	_elementAttributes : {},
	
	controller: null,
	element: null,
	initialPosition : {},
	
	dragActive : false,
	mouseOffset : null,
	
	enabled : true,
	drops : null,
	
	options: {},

	// constructor
	__construct : function(controller, element, options){
		// check the integrity of the elements
		if(!__valid(__id(controller)) || !__valid(__id(element))){
			syslib.messages.error("syslib.ui.Drag.__construct(): Invalid element!");
		}
		
		// get the element and the controller
		this.controller = __id(controller);
		this.element 	= __id(element);

		// set the options
		this.options = __extend({}, options);

		// set the default values of some parameters
		this.drops = [];
		this.dragActive = false;
		this.enabled = true;
		this.mouseOffset = null;
		
		// get the parent node
		this.parent  = this.element.parentNode;

		// update the style, if allowed
		if(this.options.updateStyle !== false){
			syslib.element.updateStyle(this.controller, {
				cursor: 'move'
			});
		}

		// set the evetns
		syslib.event.listen('mousedown', this.controller, this.mouseDown.applyTo(this));
		syslib.event.listen('mousemove', document, this.mouseMove.applyTo(this));
		syslib.event.listen('mouseup', document, this.mouseUp.applyTo(this));
		
		// get the inicial position
	},

	disable : function(){
		// set as disabled
		this.enabled = false;
		
		// log
		syslib.messages.info("Drag " + this.controller.id + " was been disabled");
	},

	enable : function(){
		// set as enabled
		this.enabled = true;
		
		// log
		syslib.messages.info("Drag " + this.controller.id + " was been enabled");
	} ,

	mouseDown : function(evt){
		// check if the drag is enabled
		if(this.enabled === false || syslib.event.isLeftClick(evt) === false){
			return false;
		}

		// set the drag as active
		this.dragActive  			  		= true;
		
		// store the element attributes
		this._elementAttributes.zIndex	  	= this.element.style.zIndex;
		this._elementAttributes.position 	= this.element.style.position;
		this._elementAttributes.left		= this.element.style.left;
		this._elementAttributes.top			= this.element.style.top;
		this._elementAttributes.margin		= this.element.style.margin;
		
		// get the mouse offset
		this.mouseOffset = this.getMouseOffset(evt);

		// get the real position of the element (relative to body, correct scrollbar errors)
		this.initialPosition = this.getRealPosition(this.element);

		// update the style
		syslib.element.updateStyle(this.element, {
			position: 'absolute',
			margin: '0',
			zIndex: parseInt(syslib.ui.Drag.zIndex++),
			left: this.initialPosition[0],
			top: this.initialPosition[1]
		});

		// check if alpha apply is needed
		if(this.options.alpha === true){
			syslib.element.updateStyle(this.element, {
				'filter': 'alpha(opacity=50)',
				'-moz-opacity': '.50',
				'opacity': '.50'
			});
		}

		// append to body
		this.element.parentNode.removeChild(this.element);
		document.body.appendChild(this.element);

		// call the onStart function, if setted
		if(typeof this.options.onStart === 'function'){
			this.options.onStart({
				initialX : this.initialPosition[0], 
				initialY : this.initialPosition[1], 
				x : this.initialPosition[0], 
				y : this.initialPosition[1]
			});
		}
		
		// log
		syslib.messages.info("Drag " + this.controller.id + " started");
		
		// return false to stop the event
		return false;
	},

	mouseUp : function(evt){
		// check if the drag is active
		if(this.dragActive === true){
			// set the drag as inactive
			this.dragActive = false;
			
			// get the element final position
			var finalPosition = this.getRealPosition(this.element);

			// reset the alpha, if needed
			if(this.options.alpha === true){
				syslib.element.updateStyle(this.element, {
					'filter': 'alpha(opacity=100)',
					'-moz-opacity': '1',
					'opacity': '1'
				});
			}

			// check if the element has been dropped somewhere
			for(var i = 0; i < this.drops.length; i++){
				var drop   = this.drops[i];
				var psdrop = drop.getCoords();
				var mousex = syslib.event.mouseX(evt);
				var mousey = syslib.event.mouseY(evt);

				if(mousex >= psdrop.x1 && mousex <= psdrop.x2 && mousey >= psdrop.y1 && mousey <= psdrop.y2){
					// call the onDrop event
					drop.onDrop(this.element);
				}
			}
			
			// check if the element must be resetted to the inicial position
			if(this.options.reset){
				// update the css data
				syslib.element.updateStyle(this.element, {
					position: this._elementAttributes.position,
					top: this._elementAttributes.top,
					left: this._elementAttributes.left,
					margin: this._elementAttributes.margin,
					zIndex: this._elementAttributes.zIndex
				});
				
				// get the brother
				if(syslib.dom.next(this.element) !== undefined){
					brother = syslib.dom.next(this.element);
				} else if(syslib.dom.previous(this.element) !== undefined){
					brother = syslib.dom.previous(this.element);
				} else {
					brother = false;
				}
					
				// append to the original container
				if(this.brother){
					this.element.parentNode.insertBefore(this.element, this.brother);
				} else {
					this.element.parentNode.appendChild(this.element);
				}
			}
			
			// disable the drops
			this.deactivateDrops();
			
			// call the onEnd function, if setted
			if(typeof this.options.onEnd === 'function'){
				this.options.onEnd({
					initialX : this.initialPosition[0], 
					initialY : this.initialPosition[1], 
					x : finalPosition[0], 
					y : finalPosition[1]
				});
			}
			
			// set the initial position as this final position
			if(!this.options.reset){
				this.initialPosition = finalPosition;
			}
			
			// log
			syslib.messages.info("Drag " + this.controller.id + " ended");
		}
	},

	mouseMove : function(evt){
		// check if the drag is active
		if(this.dragActive === true){
			// get the mouse position
			var mousePos = [syslib.event.mouseX(evt), syslib.event.mouseY(evt)];
			
			// calculate the element position, based on the mouse offset
			var left	= (parseInt(mousePos[0]) - parseInt(this.mouseOffset[0])) + 'px';
			var top		= (parseInt(mousePos[1]) - parseInt(this.mouseOffset[1])) + 'px';

			// x move
			if(this.options.xmove !== false){
				this.element.style.left = left;
			}
			
			// y move
			if(this.options.ymove !== false){
				this.element.style.top = top;
			}
			
			// call the onDrag function
			if(typeof this.options.onDrag == 'function'){
				this.options.onDrag({
					initialX : this.initialPosition[0], 
					initialY : this.initialPosition[1], 
					x : parseInt(left),  
					y : parseInt(top)
				});
			}

			// check if any drop must be activated
			for(var i = 0; i < this.drops.length; i++){
				var drop   = this.drops[i];
				var psdrop = drop.getCoords();
				var mousex = syslib.event.mouseX(evt);
				var mousey = syslib.event.mouseY(evt);

				if(mousex >= psdrop.x1 && mousex <= psdrop.x2 && mousey >= psdrop.y1 && mousey <= psdrop.y2){
					if(!drop.active){ drop.activate(this.element); }
				} else {
					if(drop.active){ drop.deactivate(this.element); }
				}
			}
			
			// return false to stop the event
			return false;
		}
	},

	registerDroppable : function(droppable){
		if(droppable.type === 'droppable'){
			this.drops.push(droppable);
			syslib.messages.info("Droppable " + droppable.element.id + " registered on drag " + this.controller.id);
		} else {
			syslib.messages.error("Drop " + droppable.element.id + " is invalid an could not be registered!");
		}

	},

	deactivateDrops : function(){
		for(var i = 0; i < this.drops.length; i++){
			var drop = this.drops[i];
			drop.deactivate(this.element);
		}
	},

	getRealPosition : function(element){
		var top			= 0;
		var left		= 0;

		try{
			while(syslib.util.valid(element.offsetParent)){
				left += (element.offsetLeft - element.offsetParent.scrollLeft);
				top  += (element.offsetTop - element.offsetParent.scrollTop);
				element = element.offsetParent;
			}
			top  += (element.offsetLeft);
			left += (element.offsetTop);
		} catch(e){
			alert(e.message);
		}

		return [left, top];
	},

	getMouseOffset : function(evt){
		try{
			var mousepos 	= [syslib.event.mouseX(evt), syslib.event.mouseY(evt)];
			var elemtpos	= this.getRealPosition(this.element);

			return [mousepos[0] - elemtpos[0], mousepos[1] - elemtpos[1]];
		} catch(e){
			alert(e.message);
		}
	}
};
syslib.ui.Drag.zIndex = 1500;

/**
 * Drop class
 * @class syslib.ui.Drop
 * @author Gabriel Ricci
 */
syslib.ui.Drop = __class();
syslib.ui.Drop.prototype = {
	type : 'droppable',
	element : null,
	options : {},

	active : false,

	__construct : function(element, options){
		if(__id(element)){
			this.element = __id(element);
		} else {
			return false;
		}

		if(typeof options == 'object'){
			this.options = options;
		}
	},

	onDrop : function(dropped){
		if(typeof this.options.onDrop === 'function'){
			this.options.onDrop(this.element, dropped);
		}
	},

	activate : function(drag){
		this.active = true;
		if(typeof this.options.onEnable === 'function'){
			this.options.onEnable(this.element, drag);
		}
	},

	deactivate : function(drag){
		this.active = false;
		if(typeof this.options.onDisable === 'function'){
			this.options.onDisable(this.element, drag);
		}
	},

	getOffset : function(){
		var top = 0; var left = 0; element = this.element;
		while (element.offsetParent){
			left 	+= element.offsetLeft;
			top  	+= element.offsetTop;
			element	=  element.offsetParent;
		}

		left += element.offsetLeft;
		top  += element.offsetTop;

		return {x: left, y: top};
	},

	getCoords : function(){
		var offset 	= this.getOffset();
		var dimens	= Element.getDimensions(this.element);

		return {x1: offset.x, x2: offset.x + dimens.width, y1: offset.y, y2: offset.y + dimens.height};
	}
};

/**
 * The effects class
 * @class syslib.ui.fx
 * @author Gabriel Ricci
 * @static
 */
syslib.ui.fx = {
	MOVE 	: "syslib.ui.fx.Move",
	RESIZE 	: "syslib.ui.fx.Resize",
	ALPHA 	: "syslib.ui.fx.Alpha",
	
	isLoaded : function(effect){
		if(typeof effect == "string"){
			return __valid(eval(effect));
		}
		
	},   
	
	load : function(effect){
		// log
		syslib.messages.info("syslib.ui.fx.load(): Loading effect " + effect);
		
		// load
		syslib.io.importClass(effect, {
			onComplete : function(){
				syslib.messages.info("syslib.ui.fx.load(): Effect " + effect + " loaded");
			}
		});
	}
};

/**
 * Basic structure of a visual component
 * @class syslib.ui.UIComponent
 * @static
 * @abstract
 */
syslib.ui.UIComponent = {
	__componentName : "unknow-component", 
	__element : null, 
	__options : null, 
	__container : null, 
	
	__construct : function(){
		throw "Abstract method";
	}, 
	
	__createElement : function(){
		throw "Abstract method";
	}, 
	
	getElement : function(){
		if(!__valid(this.__element)){
			this.__createElement();
		}
		return this.__element;
	}, 
	
	appendTo : function(container){
		if(__valid(container)){
			// append
			container.appendChild(this.getElement());
			
			// set the container
			this.__container = container;
		}
	}, 
	
	appendChild : function(child){
		throw "Abstract method";
	}
};

/**
 * The tag to object conversor base class
 * @class syslib.ui.TagConversor
 * @author Gabriel Ricci
 * @static
 * @abstract
 */
syslib.ui.TagConversor = {
	__tagName : null, 
	__attributes : null, 
	__innerHTML : null, 
	__container : null,
	__parent : null, 
	
	__construct : function(){
		__tagName = null; 
		__attributes = null; 
		__innerHTML = null;
		__container = null;
		__parent = null;
	}, 
	
	execute : function(){
		throw "Abstract method";
	}, 
	
	onEnterBody : function(){
		return true;
	}, 
	
	getComponent : function(){
		throw "Abstract method";
	}
};